package keter.ssh.exec;

import java.io.File;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Lists;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;

import keter.framework.CmdException;
import keter.framework.util.IOUtil;
import keter.ssh.core.SshUtil;
import keter.ssh.model.Host;

public class Executor {
	
	private static final Logger logger = LoggerFactory.getLogger(Executor.class);

	static List<SshUtil> sshList;
	
	public static void  init(List<Host> hosts) throws Exception {
		sshList = Lists.newArrayList();
		for (Host host : hosts) {
			SshUtil ssh = SshUtil.init(host);
			sshList.add(ssh);
		}
	}
	
	public  void execute(String cmd) throws CmdException, InterruptedException{
		Validate.noNullElements(sshList,"ssh清单不能为空！");
		
	    ListeningExecutorService pool = 
	    		MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5));
	    
		for (SshUtil ssh : sshList) {
//			exec(cmd, ssh);
			ListenableFuture<String> future = pool.submit(new Callable<String>() {
                @Override
                public String call() throws Exception {
                	System.out.println("haha");
                	String result = exec(cmd, ssh);
                	System.out.println("hehe");
//                    Thread.sleep(1000 * 1);
                    return  "Task ["+Thread.currentThread().getId()+"] done !"+result;
                }
            });
	
        	Futures.addCallback(future, new FutureCallback<String>() {
              @Override
              public void onSuccess(String result) {
                  System.out.println(result);
              }

              @Override
              public void onFailure(Throwable t) {
                  t.printStackTrace();
              }
          });
		}
		
//        Thread.sleep(10 * 1000);  //wait for task done
        pool.shutdown();
	}

	private static String exec(String cmd, SshUtil ssh) throws CmdException {
		try {
			String result = 
					"------result of ["+ssh.getHost().getAddr()+"]:----------\n"+
							ssh.exec(cmd).result()+
					"------------------------\n";
			//System.out.println(result);
			return result;
		} catch (Exception e) {
			throw new CmdException("主机:"+ssh.getHost().getAddr()+"命令执行失败!",e.getCause());
		}
	}
	
	public static void download(String src,String dest) throws CmdException{
		for (SshUtil ssh : sshList) {
			try {
				ssh.download(src, dest);
				logger.info("主机{}文件传输完成!",ssh.getHost().getAddr());
			} catch (Exception e) {
				throw new CmdException("主机:"+ssh.getHost().getAddr()+"命令执行失败!",e.getCause());
			}
		}
	}
	
	/**
	 * 将文件下载到各自主机目录内
	 * @param src
	 * @param dest
	 * @throws CmdException 
	 * @author gulixing@msn.com
	 * @date   2016年7月17日
	 */
	public static void downloadToEachFolder(String src,String dest) throws CmdException{
		for (SshUtil ssh : sshList) {
			try {
				IOUtil.ensureExists(dest+"/"+ssh.getHost().getAddr());
				ssh.download(src, dest+"/"+ssh.getHost().getAddr());
				logger.info("主机{}文件传输完成，目标文件:{}",
					ssh.getHost().getAddr(),
					dest+File.separator+ssh.getHost().getAddr()+File.separator+StringUtils.substringAfterLast(src, "/"));
			} catch (Exception e) {
				throw new CmdException("主机:"+ssh.getHost().getAddr()+"命令执行失败!",e.getCause());
			}
		}
	}

}
